﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.WebSockets;

namespace z.Controllers {
	[z.Filters.InitializeSimpleMembership]
	public class OrderController : Controller {
		public ActionResult Index() {
			return View();
		}
		[Authorize]
		public ActionResult UserOrder() {
			ViewData.Add("readonly", true);
			ViewData.Add("delete", true);
			ViewData.Add("pay", true);
			return View("Table", App.db.Orders.Where(x => x.Customer.UserName == User.Identity.Name));
		}
		//[HttpPost]
		//[Authorize]
		//public ActionResult User_Edit(int ID) {
		//	var order = App.db.Orders.Where(x => x.ID == ID).Single();
		//	if ((order.UserProfile.UserName != User.Identity.Name || order.Pay_Date.HasValue)
		//		&& !User.IsInRole("Admin"))
		//		return null;
		//	return RedirectToAction("Index", "Home");
		//}
		[HttpPost]
		[Authorize]
		public ActionResult _Edit(m.db.Order In) {
				var isAdd = App.db.Orders.Where(x => x.ID == In.ID).Count() == 0;
				var m = isAdd ? App.db.Orders.Add(new m.db.Order())
					: App.db.Orders.Where(x => x.ID == In.ID).Single();
				CultureInfo enUS = new CultureInfo("en-US");
				if (User.IsInRole("Admin")) {
					m.Order_Date = In.Order_Date;
					m.Messenger = In.Messenger;
					m.Create_Date = In.Create_Date;
					m.Pay_Date = In.Pay_Date;
					m.Ship_Date = In.Ship_Date;
					m.Note = In.Note;
					m.Address = In.Address;
				}else if (User.Identity.Name == m.Customer.UserName && !m.Pay_Date.HasValue) {
					m.Order_Date = In.Order_Date;
					m.Messenger = In.Messenger;
					m.Create_Date = In.Create_Date;
					m.Note = In.Note;
					m.Address = In.Address;
					if (!(m.Order_Date > DateTime.Now.AddHours(5))) {
						ModelState["Order_Date"].Errors.Add(string.Format("Order_Date must after {0:dd/MM/yyyy hh:mm} 5 hours",DateTime.Now));
					}
					if (m.Messenger==null) {
						ModelState["Messenger"].Errors.Add("Messenger is requiered");
					}
				}
				if (ModelState.IsValid) {
					try {
						App.db.SaveChanges();
					} catch (Exception ex) {
						return null;
					}
				}
				ViewData.Add("readonly", false);
				ViewData.Add("delete", true);
				WebSocketController.SendMessenger("Order," + In.ID);
				if (
					Request.UrlReferrer.AbsolutePath == Url.Content("~/Order/Create")
					||
					Request.UrlReferrer.AbsolutePath == Url.Content("~/Order/_Edit"))
					return View("~/Views/Order/Show.aspx", m);
				return PartialView("_Row", m);
		}
		[Authorize(Roles = "Admin")]
		public ActionResult _Paid(int ID) {
			App.resetDB();
			var m = App.db.Orders.Where(x => x.ID == ID).Single();
			if (m.Pay_Date == null)
				m.Pay_Date = DateTime.Now;
			App.db.SaveChanges();
			ViewData.Add("readonly", false);
			ViewData.Add("delete", true);
			ViewData.Add("paid", true);
			return View("_Row", m);
		}
		[Authorize(Roles = "Admin")]
		public ActionResult _Add() {
			var m = new m.db.Order();
			m.Create_Date = DateTime.Now;
			WebSocketController.SendMessenger("reload");
			return PartialView("_Row", m);
		}
		[HttpPost]
		public ActionResult _Delete(int ID) {
			var order = App.db.Orders.Where(x => x.ID == ID).Single();
			if ((order.Customer.UserName != User.Identity.Name || order.Pay_Date.HasValue)
				&& !User.IsInRole("Admin"))
				return null;
			foreach (var x in order.Order_Details.ToList()) {
				App.db.Order_Details.Remove(x);
			}
			App.db.SaveChanges();
			App.db.Orders.Remove(order);
			App.db.SaveChanges();
			WebSocketController.SendMessenger("Order," + ID);
			return PartialView("Null");
		}
		[Authorize(Roles = "Admin,Mod")]
		[HttpPost]
		public ActionResult _Ship(int ID) {
			ViewData.Add("readonly", true);
			ViewData.Add("ship", true);
			var m = App.db.Orders.Where(x => x.ID == ID).Single();
			if (m.Order_Date == null || m.Pay_Date == null || m.Ship_Date != null)
				return PartialView("_Row", m);
			if (m.Pay_Date.Value.AddHours(5) > m.Order_Date.Value)
				return PartialView("_Row", m);
			m.Ship_Date = DateTime.Now;
			App.db.SaveChanges();
			WebSocketController.SendMessenger("Order," + ID);
			return PartialView("_Row", m);
		}

		[Authorize(Roles = "Admin,Mod")]
		public ActionResult _Show(int ID) {
			var m = App.db.Orders.Where(x => x.ID == ID).Single();
			if (User.IsInRole("Admin")) {
				ViewData.Add("readonly", false);
				return PartialView("_Row", m);
			} else if (User.IsInRole("Mod") && !m.Ship_Date.HasValue) {
				ViewData.Add("readonly", true);
				ViewData.Add("ship", true);
				return PartialView("_Row", m);
			}
			return null;
		}

		[Authorize(Roles = "Admin")]
		public ActionResult Administer() {
			App.resetDB();
			ViewData.Add("readonly", false);
			ViewData.Add("delete", true);
			ViewData.Add("paid", true);
			return View("Table", App.db.Orders);
		}
		[Authorize(Roles = "Admin,Mod")]
		public ActionResult AdministerShip() {
			App.resetDB();
			ViewData.Add("readonly", true);
			ViewData.Add("ship", true);
			return View("TableList", z.Controllers.App.db.Orders
				.Where(x => x.Pay_Date.HasValue && x.Order_Date.HasValue && !x.Ship_Date.HasValue).ToList()
				.SkipWhile(x => x.Pay_Date.Value.AddHours(5) > x.Order_Date.Value)
				.SkipWhile(x => x.Order_Date.Value > DateTime.Now.AddHours(24)).ToList());
		}
		private m.db.Order generalOrder(string strOD) {
			var order = new m.db.Order();
			var astr = strOD.Split('|');
			foreach (var x in astr) {
				var ax = x.Split(':');
				int id, quantity;
				if (!int.TryParse(ax[0], out id))
					break;
				if (!int.TryParse(ax[1], out quantity))
					break;
				var order_detail = new m.db.Order_Detail();
				try {
					order_detail.Product = App.db.Products.Where(y => y.ID == id).Single();
					order_detail.Product_ID = id;
					order_detail.Quantity = quantity;
					order_detail.Unit_Price = order_detail.Product.Price;
					order.Order_Details.Add(order_detail);
				} catch (Exception ex) {
				}
			}
			return order;
		}
		[Authorize]
		public ActionResult Create(string strOD, int OccasionID) {
			var order = generalOrder(strOD);
			order.Create_Date = DateTime.Now;
			order.Customer = App.db.UserProfiles.Where(x => x.UserName == User.Identity.Name).Single();
			order.Occasion = App.db.Occasions.Where(x => x.ID==OccasionID).Single();
			order.Address = order.Customer.Address;
			App.db.Orders.Add(order);
			try {
				App.db.SaveChanges();
			} catch (Exception ex) {
				return View("~/Views/Home/Error.aspx");
			}
			ViewData.Add("readonly", false);
			ViewData.Add("add", true);
			ViewData.Add("delete", true);
			ViewData.Add("pay", true);
			return View("~/Views/Order/Show.aspx", order);
		}
	}
}
